home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / flight / meters.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  28KB  |  1,275 lines

  1. /*
  2.  * Copyright 1984-1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*
  19.  *  flight/meters.c $Revision: 1.20 $
  20.  */
  21.  
  22. #include "flight.h"
  23.  
  24. extern short wm_allplanes;
  25.  
  26. static float xscale, yscale;
  27.  
  28. static int bar_max_x;
  29. static int bar_max_y;
  30. static float bar_ticks[9][4][2];
  31. static float bar_nums[4][2];
  32.  
  33. static float gy_triangle[3][2];
  34. static float horizon_mark[3][2];
  35. static float heading_mark[3][2];
  36.  
  37.  
  38. static int meter_x1, meter_x2, meter_y1, meter_y2;
  39. static int thrust_x1;
  40. static int heading_cx;
  41. static int speed_x1;
  42. static int climb_x1;
  43. static int fuel_x1;
  44.  
  45. #define X_ADJUST(x) (int)(xscale * (x) + 0.1)
  46. #define Y_ADJUST(y) (int)(yscale * (y) + 0.1)
  47.  
  48. #define GENBAR(x, y)                \
  49. {                        \
  50.     move2s(-x, -y);    draw2s(x, -y);        \
  51.     move2s(-x, y);    draw2s(x, y);        \
  52. }
  53.  
  54.  
  55. void reset_meters()
  56. {
  57.     clear_report_card();
  58.     if (!hud && !new_inst && !shadow)
  59.     {
  60.     clear_text_display();
  61.     draw_clear_meters();
  62.     draw_horizon_meter();
  63.     }
  64. }
  65.  
  66.  
  67.  
  68. void redraw_screen()
  69. {
  70.     /*
  71.      *  draw static stuff
  72.      */
  73.     viewport(0, xmaxwindow, 0, ymaxwindow);
  74.     ortho2(-0.5, xmaxwindow+0.5, -0.5, ymaxwindow+0.5);
  75.     COLOR(C_BLACK);
  76.     clear();            /* clear the normal planes */
  77.     if (!in_cmode)
  78.     zclear();        /* clear the z planes */
  79.  
  80.     if (bits_under)
  81.     {
  82.     drawmode(UNDERDRAW);    /* clear the underlay planes */
  83.     color(0);
  84.     clear();
  85.     }
  86.  
  87.     drawmode(over_drawmode);    /* clear the pup planes */
  88.     color(0);
  89.     clear();
  90.  
  91.     if (hud || shadow || radar)
  92.     {
  93.     drawmode(NORMALDRAW);
  94.     return;
  95.     }
  96.  
  97.     /*
  98.      *  windshield
  99.      */
  100.     if (!in_cmode)
  101.     {
  102.     color(P_ORANGE);
  103.     move2s(xmiddle, ymiddle-1);             /* center of windshield */
  104.     draw2s(xmiddle, ymiddle-16);
  105.     rects(0, ymiddle-1, xmaxwindow, ymaxwindow); /* outline windshield */
  106.  
  107.     drawmode(NORMALDRAW);
  108.     }
  109.     else
  110.     {
  111.     drawmode(NORMALDRAW);
  112.  
  113.     frontbuffer(TRUE);
  114.     color(ci_table[C_ORANGE]);
  115.     move2s(xmiddle, ymiddle-1);             /* center of windshield */
  116.     draw2s(xmiddle, ymiddle-16);
  117.     rects(0, ymiddle-1, xmaxwindow, ymaxwindow); /* outline windshield */
  118.     frontbuffer(FALSE);
  119.     }
  120.  
  121.     if (new_inst)
  122.     draw_instruments();
  123.     else
  124.     init_meters();
  125. }
  126.  
  127.  
  128. void init_meters()
  129. {
  130.     init_meter_sizes((int)(62*xscale), (int)(266*yscale));
  131.  
  132.     viewport(inst_x1, inst_x2, inst_y1, inst_y2);
  133.     ortho2(inst_x1-0.5, inst_x2+0.5, inst_y1-0.5, inst_y2+0.5);
  134.  
  135.     drawmode(over_drawmode);
  136.     color(P_ORANGE);
  137.  
  138.     /*
  139.      *  label meters
  140.      */
  141.     cmov2s(thrust_x1, meter_y1-20);        charstr("Thrust");
  142.     cmov2s(speed_x1, meter_y1-20);        charstr("Speed");
  143.     cmov2s(speed_x1, meter_y1-36);        charstr("knots");
  144.     cmov2s(climb_x1, meter_y1-20);        charstr("Climb");
  145.     cmov2s(climb_x1, meter_y1-36);        charstr(" fpm");
  146.     cmov2s(climb_x1+70, meter_y1-20);        charstr("G-force");
  147.     cmov2s(xmiddle-30, meter_y1-20);        charstr("Horizon");
  148.     cmov2s(heading_cx-30, meter_y1-20);    charstr("Heading");
  149.     cmov2s(fuel_x1+8, meter_y1-20);        charstr("Fuel");
  150.  
  151.  
  152.     /*
  153.      *  set up bar meters
  154.      */
  155.     pushmatrix();
  156.     translate((float)thrust_x1, (float)meter_y1, 0.0);
  157.     draw_meter_static();
  158.     translate((float)(speed_x1-thrust_x1), 0.0, 0.0);
  159.     draw_meter_static();
  160.     translate((float)(climb_x1-speed_x1), 0.0, 0.0);
  161.     draw_meter_static();
  162.     translate((float)(fuel_x1-climb_x1), 0.0, 0.0);
  163.     draw_meter_static();
  164.     popmatrix();
  165.  
  166.     /*
  167.      *  set up gforce meters
  168.      */
  169.     drawmode(over_drawmode);
  170.     color(P_ORANGE);
  171.     pushmatrix();
  172.     translate(412.0*xscale, 0.0, 0.0);
  173.     scale(xscale, yscale, 0.0);
  174.     draw_gforce_static();
  175.     popmatrix();
  176.  
  177.     /*
  178.      *  set up heading/radar meter
  179.      */
  180.     polf2(3, heading_mark);
  181.     pushmatrix();
  182.     translate((float)heading_cx, 266.0*yscale, 0.0);
  183.     scale(1.35*yscale, 1.35*yscale, 1.35*yscale);
  184.     if (bits_under)
  185.     {
  186.     drawmode(UNDERDRAW);
  187.     color(U_BROWN);
  188.     circfs(0, 0, 102);
  189.     }
  190.     drawmode(over_drawmode);
  191.     color(P_ORANGE);            /* draw plane        */
  192.     if (!dogfight)
  193.     {
  194.     move2s(0, 0);
  195.     draw2s(2, -10);
  196.     draw2s(12, -18);
  197.     draw2s(12, -20);
  198.     draw2s(2, -14);
  199.     draw2s(2, -20);
  200.     draw2s(5, -23);
  201.     draw2s(-5, -23);
  202.     draw2s(-2, -20);
  203.     draw2s(-2, -14);
  204.     draw2s(-12, -20);
  205.     draw2s(-12, -18);
  206.     draw2s(-2, -10);
  207.     draw2s(0, 0);
  208.     }
  209.     else
  210.     rectfs(-1, -1, 1, 1);
  211.     popmatrix();
  212.  
  213.     /*
  214.      *  set up horizon meter
  215.      */
  216.     polf2(3, horizon_mark);
  217.  
  218.     viewport(X_ADJUST(515), X_ADJUST(765),
  219.          meter_y1, meter_y2);
  220.  
  221.     ortho2(-90.0, 90.0, -90.0, 90.0);
  222.     if (bits_under)
  223.     {
  224.     drawmode(UNDERDRAW);
  225.     color(U_BROWN);
  226.     clear();
  227.     color(0);
  228.     draw_blanking();
  229.     }
  230.     drawmode(over_drawmode);
  231.     color(P_ORANGE);
  232.     rectfs(-66, -2, -30, 0);        /* W    */
  233.     rectfs(66, -2, 30, 0);
  234.     linewidth(2);
  235.     move2s(33, -6);
  236.     draw2s(20, -20);
  237.     draw2s(0, 0);
  238.     draw2s(-20, -20);
  239.     draw2s(-33, -6);
  240.     linewidth(1);
  241.     move2s(-60, -90);    draw2s(-60, -83);    /* yaw lines    */
  242.     move2s(-30, -90);    draw2s(-30, -86);
  243.     move2s(0, -90);    draw2s(0, -83);
  244.     move2s(30, -90);    draw2s(30, -86);
  245.     move2s(60, -90);    draw2s(60, -83);
  246.  
  247.     drawmode(NORMALDRAW);
  248. }
  249.  
  250.  
  251.  
  252. /*
  253.  *  clear the text display area
  254.  */
  255. void clear_text_display()
  256. {
  257.     viewport(X_ADJUST(124), X_ADJUST(1125), Y_ADJUST(413), Y_ADJUST(460));
  258.     ortho2(99.0, 900.0, 300.0, 345.0);
  259.     COLOR(C_BLACK);
  260.     clear();
  261.     COLOR(C_WHITE);
  262. }
  263.  
  264. /*
  265.  *  clear ALL the meters
  266.  */
  267. void draw_clear_meters()
  268. {
  269.     viewport(meter_x1-2, meter_x2+2, meter_y1-2, meter_y2+2);
  270.     COLOR(C_BLACK);
  271.     clear();
  272. }
  273.  
  274.  
  275.  
  276. void draw_slow_meters()
  277. {
  278.     register int i;
  279.     float r, sin, cos;
  280.     char buf[32];
  281.  
  282.     COLOR(C_WHITE);
  283.     pushmatrix();
  284.     translate(457.0*xscale, -133.0/8.0/GRAVITY * lift * yscale, 0.0);
  285.     draw_gforce();
  286.     popmatrix();
  287.  
  288.     COLOR(C_WHITE);
  289.     sprintf(buf, "%d", airspeed);
  290.     cmov2s(speed_x1+8, meter_y1+5);
  291.     charstr(buf);
  292.     sprintf(buf, "%d", (climbspeed << 6) - (climbspeed << 2));
  293.     cmov2s(climb_x1+3, meter_y1+5);        /* (x*64) - (x*4) */
  294.     charstr(buf);
  295.  
  296.     /*
  297.      *  HEADING meter
  298.      */
  299.     pushmatrix();
  300.     translate((float)heading_cx, 266.0*yscale, 0.0);
  301.     scale(1.35*yscale, 1.35*yscale, 1.35*yscale);
  302.     if (!bits_under)
  303.     {
  304.     COLOR(C_INST_BROWN);
  305.     circfs(0, 0, 102);
  306.     }
  307.     rotate(-azimuth, 'z');
  308.     COLOR(C_WHITE);
  309.     for (i = 0; i < 3600; i += 100)
  310.     {
  311.     gl_sincos(i, &sin, &cos);
  312.     move2(100.0 * sin, 100.0 * cos);
  313.     if (i == 300 || i == 600 || i == 1200 || i == 1500 ||
  314.         i == 2100 || i == 2400 || i == 3000 || i == 3300)
  315.         r = 75.0;    /* long line    */
  316.     else
  317.         r = 90.0;    /* short line    */
  318.     draw2(r * sin, r * cos);
  319.     }
  320.     move2s(-7, 60);    /* N    */
  321.     draw2s(-7, 80);
  322.     draw2s(7, 60);
  323.     draw2s(7, 80);
  324.     move2s(60, -7);    /* E    */
  325.     draw2s(60, 7);
  326.     draw2s(80, 7);
  327.     draw2s(80, -7);
  328.     move2s(70, 7);
  329.     draw2s(70, -3);
  330.     move2s(-80, -9);    /* W    */
  331.     draw2s(-60, -4);
  332.     draw2s(-70, 0);
  333.     draw2s(-60, 4);
  334.     draw2s(-80, 9);
  335.     move2s(-7, -78);    /* S    */
  336.     draw2s(-5, -80);
  337.     draw2s(7, -80);
  338.     draw2s(7, -70);
  339.     draw2s(-7, -70);
  340.     draw2s(-7, -60);
  341.     draw2s(5, -60);
  342.     draw2s(7, -62);
  343.     scale(0.004, -0.004, 0.004);    /* scale down (y=-z)    */
  344.     draw_radar_objects();
  345.     COLOR(C_WHITE);
  346.     popmatrix();
  347. }
  348.  
  349.  
  350.  
  351. void draw_horizon_meter()
  352. {
  353.     static Scoord yaw_indicator[][2] = {{0, -85}, {-4, -81}, {4, -81}};
  354.  
  355.     /*
  356.      *  set up horizon meter
  357.      */
  358.     viewport(X_ADJUST(515), X_ADJUST(765), meter_y1, meter_y2);
  359.     if (!bits_under)
  360.     {
  361.     COLOR(C_INST_BROWN);
  362.     clear();
  363.     }
  364.  
  365.     ortho2(-90.0, 90.0, -90.0, 90.0);
  366.     pushmatrix();
  367.     COLOR(C_BLUE);
  368.     rotate(-twist, 'z');
  369.     translate(0.0, -0.1 * elevation, 0.0);
  370.     rectfs(-150, 0, 150, 500);
  371.  
  372.     COLOR(C_WHITE);
  373.     move2s(-30, 0);    draw2s(30, 0);
  374.     GENBAR(30, 80);
  375.     GENBAR(10, 60);
  376.     GENBAR(15, 40);
  377.     GENBAR(10, 20);
  378.  
  379.     popmatrix();                /* return to ortho    */
  380.     COLOR(C_BLACK);
  381.     draw_blanking();
  382.  
  383.     COLOR(C_RED);
  384.     pushmatrix();            /* save matrix for wing_stall    */
  385.     translate(rudder * 75.0, 0.0, 0.0); /* map 0.8 => 60    */
  386.     polf2s(3, yaw_indicator);
  387.     popmatrix();
  388. }
  389.  
  390. void draw_wing_stall()
  391. {
  392.     COLOR(C_WHITE);
  393.     cmov2s(-32, 4);
  394.     charstr("WING-STALL");
  395. }
  396.  
  397. void draw_g_limit()
  398. {
  399.     COLOR(C_WHITE);
  400.     cmov2s(-24, 4);
  401.     charstr("G-LIMIT");
  402. }
  403.  
  404. void draw_auto_pilot()
  405. {
  406.     COLOR(C_WHITE);
  407.     cmov2s(-40, 20);
  408.     charstr("AUTO-PILOT");
  409. }
  410.  
  411. void draw_crash_meters()
  412. {
  413.     viewport(meter_x1, meter_x2, meter_y1, meter_y2);
  414.     COLOR(C_WHITE);
  415.     setpattern(CRASH_PATTERN);
  416.     clear();
  417.     setpattern(0);
  418. }
  419.  
  420.  
  421.  
  422. /************************************************************
  423. /*    Trash procedures
  424. /************************************************************/
  425. void draw_blanking()
  426. {
  427.     static Scoord blanking1[][2] = { {91, 91}, {70, 91}, {91, 70} };
  428.     static Scoord blanking2[][2] = { {-91, 91}, {-91, 70}, {-70, 91} };
  429.     static Scoord blanking3[][2] = { {-91, -91}, {-70, -91}, {-91, -70} };
  430.     static Scoord blanking4[][2] = { {91, -91}, {91, -70}, {70, -91} };
  431.  
  432.     polf2s(3, blanking1);
  433.     polf2s(3, blanking2);
  434.     polf2s(3, blanking3);
  435.     polf2s(3, blanking4);
  436. }
  437.  
  438.  
  439. void draw_meter(int val)
  440. {
  441.     short i;
  442.  
  443.     if (val >= 0)
  444.     {
  445.     if (val > 100) val = 100;
  446.     i = bar_max_y * (val / 100.0);
  447.  
  448.     if (i < bar_max_y && !bits_under)
  449.     {
  450.         COLOR(C_INST_BROWN);
  451.         rectfs(0, i, bar_max_x, bar_max_y);
  452.     }
  453.  
  454.     COLOR(C_BLUE);
  455.     rectfs(0, 0, bar_max_x, i);
  456.     }
  457.     else
  458.     {
  459.     if (val < -100) val = -100;
  460.     i = bar_max_y * (-val / 100.0);
  461.  
  462.     if (i < bar_max_y && !bits_under)
  463.     {
  464.         COLOR(C_INST_BROWN);
  465.         rectfs(0, i, bar_max_x, bar_max_y);
  466.     }
  467.  
  468.     COLOR(C_RED);
  469.     rectfs(0, 0, bar_max_x, i);
  470.     }
  471.  
  472.  
  473. }
  474.  
  475.  
  476. void draw_meter_bar(int val, int bar)
  477. {
  478.     short i;
  479.  
  480.     draw_meter(val);
  481.  
  482.     if (bar != val)
  483.     {
  484.     if (bar >= 0)
  485.     {
  486.         COLOR(C_GREEN);
  487.         if (bar > 100) bar = 100;
  488.         i = bar_max_y * (bar / 100.0);
  489.     }
  490.     else
  491.     {
  492.         COLOR(C_YELLOW);
  493.         if (bar < -100) bar = -100;
  494.         i = bar_max_y * (-bar / 100.0);
  495.     }
  496.  
  497.     rectfs(0, i-2, bar_max_x, i);
  498.     }
  499. }
  500.  
  501.  
  502.  
  503. /*
  504.  *  draw the radar display
  505.  */
  506. void draw_radar_objects()
  507. {
  508.     Plane pp, ptemp, *ptemp2;
  509.  
  510.     pp = planes[0];
  511.  
  512.     translate(-pp->x, -pp->z, 0.0);
  513.  
  514.     /*
  515.      *  other planes
  516.      */
  517.     if (dogfight)
  518.     {
  519.     FOR_EACH_PLANE (ptemp, ptemp2)
  520.         if (ptemp != pp)
  521.         {
  522.         if (ptemp->y <= pp->y)
  523.             COLOR(C_GREEN);
  524.         else
  525.             COLOR(C_RED);
  526.         if (hud)
  527.         {
  528.             cmov2(ptemp->x, ptemp->z); charstr("^");
  529.         }
  530.         else
  531.             rectf(ptemp->x - 200.0, ptemp->z - 200.0,
  532.               ptemp->x + 200.0, ptemp->z + 200.0);
  533.         }
  534.     }
  535.  
  536.     /*
  537.      *  missiles
  538.      */
  539.     COLOR(C_RED);
  540.     FOR_EACH_PLANE (ptemp, ptemp2)
  541.     if (ptemp->mstatus && ptemp->mtype != TYPE_CANNON)
  542.         pnt2(ptemp->mx, ptemp->mz);
  543.  
  544.     /*
  545.      *  the runway
  546.      */
  547.     COLOR(C_BLUE);
  548.     move2(0.0, 0.0);
  549.     draw2(0.0, -8500.0);
  550. }
  551.  
  552.  
  553.  
  554. static char *numbers[] = {
  555.      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",  "8",  "9",
  556.     "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
  557.     "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
  558.     "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
  559.     "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
  560.     "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
  561.     "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
  562.     "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
  563.     "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
  564.     "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100"
  565. };
  566.  
  567. static float rhaws[][2] = {     /* 20 point unit circle */
  568.      0.000000,  1.000000,
  569.      0.309017,  0.951057,
  570.      0.587785,  0.809017,
  571.      0.809017,  0.587785,
  572.      0.951057,  0.309017,
  573.      1.000000,  0.000000,
  574.      0.951057, -0.309017,
  575.      0.809017, -0.587785,
  576.      0.587785, -0.809017,
  577.      0.309017, -0.951057,
  578.      0.000000, -1.000000,
  579.     -0.309017, -0.951057,
  580.     -0.587785, -0.809017,
  581.     -0.809017, -0.587785,
  582.     -0.951057, -0.309017,
  583.     -1.000000,  0.000000,
  584.     -0.951057,  0.309017,
  585.     -0.809017,  0.587785,
  586.     -0.587785,  0.809017,
  587.     -0.309017,  0.951057};
  588.  
  589. char alt_text[16];        /* global altitude text */
  590. char mach_text[8];        /* global mach number text */
  591. char g_text[8];            /* global g-force text */
  592.  
  593.  
  594. draw_hud(p, tick, vx, vy, vz, vv, mach, gf,
  595.      wheels, flaps, spoilers, autop, fuel, thrust, throttle)
  596.     register Plane p;
  597.     int tick;
  598.     float vx, vy, vz;
  599.     int vv;
  600.     float mach, gf;
  601.     int wheels, flaps, spoilers, autop, fuel, thrust, throttle;
  602. {
  603.     register char buf[32];
  604.     register int a, i, x, y;
  605.     float k, r, sin, cos, temp;
  606.  
  607.     static float yaw_x_trans = 0.0, yaw_y_trans = 0.0;
  608.     static int heading_rotate = 0;
  609.  
  610.     extern char alt_text[], mach_text[], g_text[];
  611.     extern rockets, sidewinders;
  612.  
  613. #ifdef DEBUG
  614.     if (debug & (1<<9))
  615.     {
  616.     ortho2(-0.5, xmaxwindow+0.5, -0.5, ymaxwindow+0.5);
  617.     draw_report();            /* display messages    */
  618.     COLOR(C_ORANGE);
  619.     goto skipit;
  620.     }
  621. #endif /* DEBUG */
  622.  
  623.     /* this should be moved to overlap graphics if possible    */
  624.     if ((tick & 3) == 2)        /* do every fourth frame */
  625.     {
  626.     sprintf(mach_text, "%.2f", mach);    /* update text    */
  627.     sprintf(g_text, "%.1f", gf);
  628.  
  629.     y = p->y;
  630.     if (y >= 1000)
  631.         sprintf(alt_text, "%3d,%03d", y/1000, y%1000);
  632.     else
  633.         sprintf(alt_text,"    %3d", y);
  634.     temp = (vv < 0)? -vv : vv;
  635.     if (temp > 300) alt_text[4] = '0';
  636.     if (temp > 30) alt_text[5] = '0';
  637.     alt_text[6] = '0';
  638.     }
  639.  
  640.     COLOR(C_ORANGE);
  641.  
  642.     /*
  643.      *  assume viewport is whole screen
  644.     ortho2(-0.5, xmaxwindow+0.5, -0.5, ymaxwindow+0.5);
  645.      */
  646.  
  647.     cmov2s(HUD_MARGIN-30, 30); charstr(plane_type);    /* plane's text */
  648.     sprintf(buf, "%.1f", Lmax);
  649.     cmov2s(HUD_MARGIN-30, 50); charstr(buf);        /* max G force */
  650.  
  651.     x = xmiddle;
  652.     y = 75;                    /* marker for heading    */
  653.     move2s(x, y);    draw2s(x, y+15);
  654.  
  655.     y = (ymaxwindow+1)/2;
  656.     move2s(x+4, y);    draw2s(x+16, y);    /* nose cross hairs    */
  657.     move2s(x-4, y);    draw2s(x-16, y);
  658.     move2s(x, y+4);    draw2s(x, y+16);
  659.     move2s(x, y-4);    draw2s(x, y-16);
  660.  
  661.     x = HUD_MARGIN;                /* mach and g text    */
  662.     cmov2s(x, 290); charstr(g_text);
  663.     cmov2s(x, 75); charstr(mach_text);
  664.  
  665.     y = (ymaxwindow+1)/4;
  666.     x = HUD_MARGIN;                /* marker for airspeed    */
  667.     move2s(x, y);    draw2s(x+16, y);
  668.     cmov2s(x+4, y+4); charstr("C");
  669.  
  670.     x = xmaxwindow-HUD_MARGIN;            /* marker for altitude    */
  671.     move2s(x, y);    draw2s(x-16, y);    /* and vv (climbspeed)    */
  672.     x -= 32;    y += 30*3;
  673.     for (i=0; i<6; i++)
  674.     {
  675.     move2s(x, y); draw2s(x+8, y);        /* long tick    */
  676.     move2s(x, y-15); draw2s(x+4, y-15);    /* short tick    */
  677.     y -= 30;
  678.     }
  679.     y -= 24;
  680.     cmov2s(x-14, y); charstr("R");        /* radar altimiter    */
  681.     rects(x, y-2, x+60, y+14);
  682.     cmov2s(x-5, y); charstr(alt_text);
  683.  
  684.     pushmatrix();
  685.     translate(0.0, vv * (60.0*30.0/1000.0) ,0.0);
  686.     y = (ymaxwindow+1)/4;
  687.     move2s(x, y); draw2s(x-14, y+6);        /* draw triangle    */
  688.     draw2s(x-14, y-6); draw2s(x, y);
  689.     popmatrix();
  690.  
  691.     pushmatrix();
  692.     if (vz != 0.0)
  693.     {
  694.     k = -57.3*(ymaxwindow+1)/36.0;    /* window is 36 degrees */
  695.     yaw_x_trans = k*vx/vz;
  696.     yaw_y_trans = k*vy/vz;
  697.     }
  698.     translate(yaw_x_trans, yaw_x_trans, 0.0);
  699.     x = xmiddle;
  700.     y = (ymaxwindow+1)/2;
  701.     move2s(x+16, y);    draw2s(x+6, y);        /* draw FPM        */
  702.     draw2s(x+4, y+4);    draw2s(x, y+6);
  703.     draw2s(x, y+16);
  704.     move2s(x-16, y);    draw2s(x-6, y);
  705.     move2s(x, y+6);    draw2s(x-4, y+4);
  706.     draw2s(x-6, y);    draw2s(x-4, y-4);
  707.     draw2s(x, y-6);    draw2s(x+4, y-4);
  708.     draw2s(x+6, y);
  709.     popmatrix();
  710.  
  711.     pushviewport();
  712.     pushmatrix();
  713.     viewport(8, HUD_MARGIN-50, 8, HUD_MARGIN-50); /* RHAWS scope    */
  714.     ortho2(-100.5, 100.5, -100.0, 100.5);
  715.     COLOR(C_GREEN);
  716.     pnt2s(0, 0);
  717.     for (i = 0; i < 3600; i += 150)    /* static ticks    */
  718.     {
  719.     gl_sincos(i, &sin, &cos);
  720.     move2(100.0 * sin, 100.0 * cos);
  721.     if (i % 900 == 0) r = 20.0;
  722.     else if (i % 450 == 0) r = 75.0;
  723.     else r = 88.0;
  724.     draw2(r * sin, r * cos);
  725.     }
  726.     move2s(20, 0);
  727.     if (tick < int_tps/2)            /* RHAWS ticker        */
  728.     draw2s(20, 8);
  729.     else
  730.     draw2s(20, -8);
  731.     pushmatrix();
  732.     scale(25.0, 25.0, 1.0);
  733.     poly2(20, rhaws);
  734.     scale(2.0, 2.0, 1.0);
  735.     poly2(20, rhaws);
  736.     scale(2.0, 2.0, 1.0);
  737.     poly2(20, rhaws);
  738.     popmatrix();
  739.     if (tick & 1)                /* do every other tick    */
  740.     heading_rotate = -p->azimuth;
  741.     rotate(heading_rotate, 'z');
  742.     scale(0.004, -0.004, 0.004);    /* scale down (y=-z)    */
  743.     draw_radar_objects();
  744.     COLOR(C_WHITE);    /* NOTE: threat patches are in land2.c */
  745.     cmov2i(6000, 14000);    charstr("4");
  746.     cmov2i(-20000, 15000);    charstr("8");
  747.     cmov2i(3000, 34000);    charstr("A");
  748.     popmatrix();
  749.     popviewport();
  750.  
  751.     pushviewport();
  752.     draw_report();            /* display messages    */
  753.     popviewport();
  754.  
  755.     ortho2(-0.5, xmaxwindow+0.5, -0.5, ymaxwindow+0.5);
  756.  
  757.     COLOR(C_ORANGE);
  758.  
  759.     a = -TPS * 3600.0/6082.0 * vz;    /* airspeed meter    */
  760.     y = (ymaxwindow+1)/4 - (a%10) - 70;
  761.     x = HUD_MARGIN-8;            /* right edge        */
  762.     a = a/10 - 7;            /* starting number    */
  763.     for (i=0; i<16; i++)
  764.     {
  765.     if (a >= 0)
  766.     {
  767.         if (a % 5)
  768.         {
  769.         move2s(x, y);    draw2s(x-4, y);
  770.         }
  771.         else
  772.         {
  773.         move2s(x, y);    draw2s(x-8, y);
  774.         cmov2s(x-8-30, y-4);
  775.         if (a<10) charstr("  "), charstr(numbers[a]);
  776.         else if (a<100) charstr(" "), charstr(numbers[a]);
  777.         else
  778.         {
  779.             sprintf(buf, "%3d", a);
  780.             charstr(buf);
  781.         }
  782.         }
  783.     }
  784.     a++;
  785.     y += 10;
  786.     }
  787.  
  788.     a = 0.1 * p->y;            /* altitude in 10's    */
  789.     x = xmaxwindow-HUD_MARGIN+4;
  790.     y = (ymaxwindow+1)/4 - (a%10) - 70;
  791.     a = a/10 - 7;            /* starting number    */
  792.     for (i=0; i < 16; i++)
  793.     {
  794.     if (a >= 0)
  795.     {
  796.         if (a % 5)
  797.         {
  798.         move2s(x, y);    draw2s(x+4, y);
  799.         }
  800.         else
  801.         {
  802.         move2s(x, y);    draw2s(x+8, y);
  803.         cmov2s(x+10, y-4);
  804.         if (a < 10)
  805.         {
  806.             charstr("   ");
  807.             charstr(numbers[a]);
  808.         }
  809.         else
  810.         {
  811.             int j=a/10;
  812.  
  813.             if (j<10)
  814.             charstr(" ");
  815.             else if (j >= 100)
  816.             charstr(numbers[j/100]);
  817.             charstr(numbers[j%100]);
  818.             charstr(",");
  819.             charstr(numbers[a%10]);
  820.         }
  821.         }
  822.     }
  823.     a++;
  824.     y += 10;
  825.     }
  826.  
  827.     a = 3600-p -> azimuth;        /* heading in tenth's    */
  828.     x = xmiddle - (a%50) - 100;
  829.     y = 75-4;
  830.     a = a/50 - 2;            /* heading in 5's    */
  831.     for (i=0; i<6; i++)
  832.     {
  833.     if (a < 0) a += 360/5;    /* wrap around        */
  834.     if (a >= 360/5) a -= 360/5;
  835.     if (a & 1)
  836.     {
  837.         move2s(x, y);    draw2s(x, y-4);
  838.     }
  839.     else
  840.     {
  841.         move2s(x, y);    draw2s(x, y-8);
  842.         cmov2s(x-8, y-9-12);
  843.         if (a<20) charstr("0");
  844.         charstr(numbers[a>>1]);
  845.     }
  846.     a++;
  847.     x += 50;
  848.     }
  849.  
  850.     pushmatrix();
  851.     pushviewport();
  852.     viewport(xmiddle-200, xmiddle+200, 75, (ymaxwindow+1)*3/4);
  853.     ortho2(-200.5, 200.5, 74.5-(ymaxwindow+1)/2, (ymaxwindow+1)/4+0.5);
  854.     rotate(-p->twist, 'z');    /* rotate about nose marker    */
  855.     a = p -> elevation;        /* elevation in tenths        */
  856.     i = a%50;
  857.     y = i * -(ymaxwindow+1)/36/10 - 1 * (ymaxwindow+1)*5/36;
  858.     a = (a-i)/10 - 1*5;            /* starting number    */
  859.  
  860.     for (i=0; i<4; i++)
  861.     {
  862.     if (a >= -90 && a <= 90)
  863.     {
  864.         if (a > 0)
  865.         {
  866.         move2s(25, y); draw2s(75, y); draw2s(75, y-12);
  867.         cmov2s(77, y-12); charstr(numbers[a]);
  868.         move2s(-25, y); draw2s(-75, y); draw2s(-75, y-12);
  869.         cmov2s(-77-20, y-12); charstr(numbers[a]);
  870.         }
  871.         else if (a < 0)
  872.         {
  873.         setlinestyle(1);
  874.         move2s(25, y); draw2s(75, y); draw2s(75, y+12);
  875.         cmov2s(77, y); charstr(numbers[-a]);
  876.         move2s(-25, y); draw2s(-75, y); draw2s(-75, y+12);
  877.         cmov2s(-77-20, y); charstr(numbers[-a]);
  878.         setlinestyle(0);
  879.         }
  880.         else            /* 0 marker    */
  881.         {
  882.         move2s(25, y);    draw2s(75, y);
  883.         move2s(-25, y);    draw2s(-75, y);
  884.         }
  885.     }
  886.     a += 5;
  887.     y += 5*(ymaxwindow+1)/36;
  888.     }
  889.     popmatrix ();
  890.     popviewport();
  891.  
  892.     ortho2(-0.5, xmaxwindow+0.5, -0.5, ymaxwindow+0.5);
  893.  
  894.     x = xmaxwindow-HUD_MARGIN-32-14-20;
  895.     if (wheels)
  896.     {
  897.     cmov2s(x, 50);    charstr("L");
  898.     }
  899.     if (flaps)
  900.     {
  901.     cmov2s(x, 30);
  902.     charstr("Flap:"); charstr(numbers[flaps]);
  903.     }
  904.     if (spoilers)
  905.     {
  906.     cmov2s(x+80, 30);
  907.     charstr("Spoilr:"); charstr(numbers[spoilers]);
  908.     }
  909.     if (autop)
  910.     {
  911.     cmov2s(x-60, 10);    charstr("Auto");
  912.     }
  913.     cmov2s(x, 10);
  914.     charstr("Fuel:");
  915.     if ((fuel == 0) || (fuel > 10))
  916.     charstr(numbers[fuel]);
  917.     else if (fuel < 0)
  918.     charstr("E");
  919.     else
  920.     /*
  921.      *  make fuel flash in the 1-10 % range
  922.      */
  923.     if(tick & 2)
  924.         charstr(numbers[fuel]);
  925.     else
  926.         charstr("    ");
  927.  
  928.     cmov2s(x+80, 10);
  929.     charstr("Thrust:");
  930.     if (thrust>=0)
  931.     charstr(numbers[thrust]);
  932.     else
  933.     {
  934.     charstr("-");
  935.     charstr(numbers[-thrust]);
  936.     }
  937.  
  938.     cmov2s(x+190, 10);
  939.     charstr("Throttle:");
  940.     if (throttle>=0)
  941.     charstr(numbers[throttle]);
  942.     else
  943.     {
  944.     charstr("-");
  945.     charstr(numbers[-throttle]);
  946.     }
  947.  
  948.     x = HUD_MARGIN+40;
  949.     if (rockets)
  950.     {
  951.     strcpy(buf, "RRRRRRRRRR");    buf[rockets] = '\0';
  952.     cmov2s(x, 30);    charstr(buf);
  953.     }
  954.     if (sidewinders)
  955.     {
  956.     strcpy(buf, "SSSSSSSSSS");    buf[sidewinders] = '\0';
  957.     cmov2s(x, 10);    charstr(buf);
  958.     }
  959. skipit:
  960.     if (p -> status <= MEXPLODE)    /* if exploding or crashed    */
  961.     {
  962.     COLOR(C_WHITE);
  963.     setpattern(CRASH_PATTERN);    /* clear in crash pattern    */
  964.     rectfi(0, ymaxwindow/2, xmaxwindow, ymaxwindow);
  965.     setpattern(0);            /* reset pattern and color    */
  966.     }
  967. }
  968.  
  969.  
  970.  
  971. /*
  972.  *  report buffer routines
  973.  */
  974.  
  975. #define MAX_REPORT_LINE 20
  976.  
  977. int report_lines = 0;
  978. struct {
  979.     float x, y;
  980.     char line[80];
  981. } report_buf[MAX_REPORT_LINE];
  982.  
  983.  
  984. void clear_report_area()
  985. {
  986.     viewport(report_x1, report_x2, report_y1, report_y2);
  987.     COLOR(C_BLACK);
  988.     clear();
  989. }
  990.  
  991.  
  992. void clear_report()
  993. {
  994.     report_lines = 0;
  995. }
  996.  
  997.  
  998. void add_report_line(float x, float y, char *line)
  999. {
  1000.     if (report_lines < MAX_REPORT_LINE-1)
  1001.     {
  1002.     report_buf[report_lines].x = x;
  1003.     report_buf[report_lines].y = y;
  1004.     strncpy(report_buf[report_lines].line, line, 80);
  1005.     report_lines++;
  1006.     }
  1007. }
  1008.  
  1009.  
  1010. void draw_report()
  1011. {
  1012.     int i;
  1013.  
  1014.     viewport(report_x1, report_x2, report_y1, report_y2);
  1015.     ortho2(report_x1-0.5, report_x2+0.5, 0.0, 1.0);
  1016.     COLOR(C_WHITE);
  1017.  
  1018.     for (i=0; i < report_lines; i++)
  1019.     {
  1020.     cmov2(report_buf[i].x, report_buf[i].y);
  1021.     charstr(report_buf[i].line);
  1022.     }
  1023. }
  1024.  
  1025. /*---------------------------------------------------------------------------*/
  1026.  
  1027.  
  1028. void draw_gforce_static()
  1029. {
  1030.     rects(25, 129, 43, 137);
  1031.     move2s(25, 167);    draw2s(33, 167);
  1032.     rects(25, 196, 33, 204);
  1033.     move2s(25, 233);    draw2s(33, 233);
  1034.     rects(25, 263, 43, 271);
  1035.     move2s(25, 300);    draw2s(33, 300);
  1036.     rects(25, 329, 33, 337);
  1037.     move2s(25, 367);    draw2s(33, 367);
  1038.     rects(25, 396, 43, 404);
  1039.     cmov2s(0, 128);    charstr("8");
  1040.     cmov2s(0, 161);    charstr("6");
  1041.     cmov2s(0, 195);    charstr("4");
  1042.     cmov2s(0, 228);    charstr("2");
  1043.     cmov2s(0, 261);    charstr("0");
  1044.     cmov2s(0, 295);    charstr("2");
  1045.     cmov2s(0, 328);    charstr("4");
  1046.     cmov2s(0, 361);    charstr("6");
  1047.     cmov2s(0, 395);    charstr("8");
  1048. }
  1049.  
  1050.  
  1051. void draw_gforce()
  1052. {
  1053.     polf2(3, gy_triangle);
  1054. }
  1055.  
  1056.  
  1057.  
  1058. void init_meter_sizes()
  1059. {
  1060.     float delta, ch, cw;
  1061.     int i;
  1062.  
  1063.     xscale = (xmaxwindow+1) / 1280.0;
  1064.     yscale = (ymaxwindow+1) / 1024.0;
  1065.  
  1066.     meter_x1 = X_ADJUST(METER_VLLX);
  1067.     meter_x2 = X_ADJUST(METER_VURX);
  1068.     meter_y1 = Y_ADJUST(METER_VLLY);
  1069.     meter_y2 = Y_ADJUST(METER_VURY);
  1070.     thrust_x1 = X_ADJUST(THRUST_LLX);
  1071.     heading_cx = X_ADJUST(HEADING_CX);
  1072.     speed_x1 = X_ADJUST(SPEED_LLX);
  1073.     climb_x1 = X_ADJUST(CLIMB_LLX);
  1074.     fuel_x1 = X_ADJUST(FUEL_LLX);
  1075.  
  1076.  
  1077.     bar_max_x = 62 * xscale;
  1078.     bar_max_y = 266 * yscale;
  1079.  
  1080.     delta = bar_max_y / 10.0;
  1081.  
  1082.     for (i = 0; i < 9; i++)
  1083.     {
  1084.     bar_ticks[i][0][X] = 0.0;
  1085.     bar_ticks[i][0][Y] = (i+1) * delta;
  1086.     bar_ticks[i][1][X] = 0.3 * bar_max_x;
  1087.     bar_ticks[i][1][Y] = (i+1) * delta;
  1088.     bar_ticks[i][2][X] = bar_max_x - 0.3 * bar_max_x;
  1089.     bar_ticks[i][2][Y] = (i+1) * delta;
  1090.     bar_ticks[i][3][X] = bar_max_x;
  1091.     bar_ticks[i][3][Y] = (i+1) * delta;
  1092.     }
  1093.  
  1094.     ch = 4.0;
  1095.     cw = 3.5;
  1096.     for (i = 0; i < 4; i++)
  1097.     {
  1098.     bar_nums[i][X] = bar_max_x / 2.0 - cw;
  1099.     bar_nums[i][Y] = (i*2+2) * delta - ch;
  1100.     }
  1101.  
  1102.     gy_triangle[0][X] = 0;
  1103.     gy_triangle[0][Y] = 267 * yscale;
  1104.     gy_triangle[1][X] = 8 * xscale;
  1105.     gy_triangle[1][Y] = 275 * yscale;
  1106.     gy_triangle[2][X] = 8 * xscale;
  1107.     gy_triangle[2][Y] = 259 * yscale;
  1108.  
  1109.     horizon_mark[0][X] = xmiddle + 1;
  1110.     horizon_mark[0][Y] = 403 * yscale;
  1111.     horizon_mark[1][X] = xmiddle + 9;
  1112.     horizon_mark[1][Y] = 415 * yscale;
  1113.     horizon_mark[2][X] = xmiddle - 7;
  1114.     horizon_mark[2][Y] = 415 * yscale;
  1115.  
  1116.     heading_mark[0][X] = heading_cx + 1;
  1117.     heading_mark[0][Y] = 403 * yscale;
  1118.     heading_mark[1][X] = heading_cx + 9;
  1119.     heading_mark[1][Y] = 415 * yscale;
  1120.     heading_mark[2][X] = heading_cx - 7;
  1121.     heading_mark[2][Y] = 415 * yscale;
  1122. }
  1123.  
  1124. void draw_meter_static()
  1125. {
  1126.     register int i;
  1127.  
  1128.     drawmode(over_drawmode);
  1129.     color(P_ORANGE);
  1130.     recti(0, 0, bar_max_x, bar_max_y);
  1131.     for(i=0; i < 9; i++)
  1132.     {
  1133.     bgnline();
  1134.     v2f(bar_ticks[i][0]);
  1135.     v2f(bar_ticks[i][1]);
  1136.     endline();
  1137.     bgnline();
  1138.     v2f(bar_ticks[i][2]);
  1139.     v2f(bar_ticks[i][3]);
  1140.     endline();
  1141.     }
  1142.     cmov2s(bar_nums[0][X], bar_nums[0][Y]);
  1143.     charstr("2");
  1144.     cmov2s(bar_nums[1][X], bar_nums[1][Y]);
  1145.     charstr("4");
  1146.     cmov2s(bar_nums[2][X], bar_nums[2][Y]);
  1147.     charstr("6");
  1148.     cmov2s(bar_nums[3][X], bar_nums[3][Y]);
  1149.     charstr("8");
  1150.  
  1151.     if (bits_under)
  1152.     {
  1153.     drawmode(UNDERDRAW);
  1154.     color(U_BROWN);
  1155.     rectfi(0, 0, bar_max_x, bar_max_y);
  1156.     }
  1157. }
  1158.  
  1159.  
  1160. void old_meters()
  1161. {
  1162.     Plane pp = planes[0], ptemp;
  1163.     int itemp;
  1164.     char charbuf[256];
  1165.  
  1166.     viewport(inst_x1, inst_x2, inst_y1, inst_y2);
  1167.     ortho2(inst_x1-0.5, inst_x2+0.5, inst_y1-0.5, inst_y2+0.5);
  1168.  
  1169.     pushmatrix();
  1170.  
  1171.     translate((float)thrust_x1, (float)meter_y1, 0.0);
  1172.     draw_meter_bar(thrust, throttle);            /* thrust meter */
  1173.  
  1174.     translate((float)(speed_x1-thrust_x1), 0.0, 0.0);
  1175.     draw_meter(airspeed/10);                /* speed meter */
  1176.  
  1177.     translate((float)(climb_x1-speed_x1), 0.0, 0.0);
  1178.     draw_meter((climbspeed>>1)+(climbspeed>>3));    /* 1/2 + 1/8 */
  1179.  
  1180.     translate((float)(fuel_x1-climb_x1), 0.0, 0.0);
  1181.     draw_meter(fuel >> 7);                /* fuel meter */
  1182.  
  1183.     popmatrix();
  1184.  
  1185.     draw_slow_meters();            /* display the text    */
  1186.  
  1187.     draw_horizon_meter();        /* resets writemask    */
  1188.     if (g_limit)
  1189.     draw_g_limit();
  1190.     else if (wing_stall)
  1191.     draw_wing_stall();
  1192.     if (autopilot_on)
  1193.     draw_auto_pilot();
  1194.     if (pp->status <= MEXPLODE)
  1195.     draw_crash_meters();
  1196.  
  1197.     /*
  1198.      *    display TEXT readouts
  1199.      */
  1200.     clear_text_display();
  1201.     if (flaps)
  1202.     {
  1203.     if (airspeed > 400-flaps)
  1204.         strcpy(charbuf, "Flaps torn off");
  1205.     else
  1206.         sprintf(charbuf, "Flaps: %2d degrees", flaps);
  1207.     cmov2s(100, 310);
  1208.     charstr(charbuf);
  1209.     }
  1210.     if (spoilers > 0)
  1211.     {
  1212.     cmov2s(280, 310);
  1213.     sprintf(charbuf, "Spoilers: %d degrees", spoilers);
  1214.     charstr(charbuf);
  1215.     }
  1216.  
  1217.     cmov2s(100, 330);
  1218.     if (wheels)
  1219.     {
  1220.     if (airspeed > 400)    /* if airspeed > 400 knots    */
  1221.         charstr("LANDING GEAR TORN OFF");
  1222.     else
  1223.         charstr("LANDING GEAR DOWN");
  1224.     }
  1225.  
  1226.     if (pp->mstatus)
  1227.     {
  1228.     cmov2s(310, 330);
  1229.     if (pp->mkill != NULL_PLANE_ID)
  1230.     {
  1231.         ptemp = lookup_plane(pp->mkill);
  1232.         if (ptemp)
  1233.         {
  1234.         sprintf(charbuf, "DESTROYED->%s", ptemp->myname);
  1235.         charstr(charbuf);
  1236.         }
  1237.     }
  1238.     else if (pp->mtype == TYPE_CANNON)
  1239.         charstr("20mm Cannon Fired");
  1240.     else if (pp->mtype == TYPE_ROCKET)
  1241.         charstr("Rocket Launched");
  1242.     else
  1243.     {
  1244.         ptemp = lookup_plane(missile_target);
  1245.         if (ptemp == NULL)
  1246.         charstr("Sidewinder Launched");
  1247.         else
  1248.         {
  1249.         sprintf(charbuf,"Sidewinder->%s", ptemp->myname);
  1250.         charstr(charbuf);
  1251.         }
  1252.     }
  1253.     }
  1254.     /*
  1255.      *  check for a locked on target
  1256.      */
  1257.     else if (missile_target != NULL_PLANE_ID)
  1258.     {
  1259.     cmov2s(310, 330);
  1260.     ptemp = lookup_plane(missile_target);
  1261.     if (ptemp != NULL)
  1262.     {
  1263.         sprintf(charbuf, "Locked on->%s", ptemp->myname);
  1264.         charstr(charbuf);
  1265.     }
  1266.     }
  1267.     cmov2s(492, 310);
  1268.     charstr(status_text);
  1269.  
  1270.     sprintf(charbuf, "Altitude: %d  Won:%d  Lost:%d",
  1271.         (int)(pp->y - plane_height), pp->won, pp->lost);
  1272.     cmov2s(612, 330);
  1273.     charstr(charbuf);
  1274. }
  1275.